﻿using EasyXaf.Sample.ODataService.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Deltas;
using Microsoft.AspNetCore.OData.Formatter;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;

namespace EasyXaf.Sample.ODataService.Controllers;

public class CompaniesController : ODataController
{
    [EnableQuery]
    public ActionResult<IEnumerable<Company>> Get()
    {
        return MockData.Companies;
    }

    [EnableQuery]
    public ActionResult<Company> Get([FromRoute] Guid key)
    {
        return MockData.Companies.FirstOrDefault(c => c.Id == key);
    }

    [EnableQuery]
    public ActionResult<IEnumerable<Department>> GetDepartments([FromRoute] Guid key)
    {
        return MockData.Companies.FirstOrDefault(c => c.Id == key)?.Departments;
    }

    public IActionResult Post([FromBody] Company company)
    {
        MockData.Companies.Add(company);
        return Created(company);
    }

    public IActionResult CreateRefToDepartments([FromRoute] Guid key, [FromBody] Uri link)
    {
        var company = MockData.Companies.SingleOrDefault(d => d.Id == key);
        if (company == null)
        {
            return NotFound();
        }

        if (!Request.TryParseRelatedKey(link, out var departmentId))
        {
            return BadRequest();
        }

        var department = MockData.Departments.SingleOrDefault(d => d.Id == Guid.Parse(departmentId));
        if (department == null)
        {
            return NotFound();
        }

        department.Company?.Departments.Remove(department);
        company.Departments.Add(department);
        department.Company = company;

        return NoContent();
    }

    public IActionResult DeleteRefToDepartments([FromRoute] Guid key)
    {
        var company = MockData.Companies.SingleOrDefault(d => d.Id == key);
        if (company == null)
        {
            return NotFound();
        }

        if (!Request.TryParseRelatedKey(new Uri(Request.Query["$id"]), out var departmentId))
        {
            return BadRequest();
        }

        var department = company.Departments.SingleOrDefault(d => d.Id == Guid.Parse(departmentId));
        if (department != null)
        {
            company.Departments.Remove(department);
        }

        return NoContent();
    }

    public IActionResult Patch([FromRoute] Guid key, [FromBody] Delta<Company> delta)
    {
        var company = MockData.Companies.SingleOrDefault(d => d.Id == key);
        if (company == null)
        {
            return NotFound();
        }

        delta.Patch(company);

        return Updated(company);
    }

    public IActionResult Delete([FromRoute] Guid key)
    {
        var company = MockData.Companies.SingleOrDefault(d => d.Id == key);
        if (company != null)
        {
            MockData.Companies.Remove(company);
        }

        return NoContent();
    }

    [HttpGet]
    public IActionResult GetDepartmentCount()
    {
        return Ok(MockData.Departments.Count());
    }

    [HttpPost]
    public IActionResult UpdateCompanyName(ODataActionParameters parameters)
    {
        foreach (var company in MockData.Companies)
        {
            company.Name = $"{parameters["prefix"]}{company.Name}";
        }
        return NoContent();
    }
}
